package com.xqq.lottery.net;

import java.io.IOException;
import java.io.InputStream;

import com.xqq.lottery.bean.MessageItem;
import com.xqq.lottery.protocal.MessageType;
import com.xqq.lottery.protocal.protobuf.Heart;
import com.xqq.lottery.util.MessageUtil;

import android.app.AlarmManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.os.IBinder;
import android.util.Log;

public class PushService extends Service {

	private static final String TAG ="PushService";
	
	private static final String HOST_IP="192.168.100.5";
	
	private static final int HOST_PORT=8811;
	
	private static final String ACTION_START = "START";
	private static final String ACTION_STOP = "STOP";
	private static final String ACTION_KEEPALIVE="KEEP_ALIVE";
	private static final String ACTION_RECONNECT = "RECONNECT";
	
	private boolean mStarted;
	private SharedPreferences mPrefs;
	public static final String PREF_STARTED = "isStarted";
	public static final String PREF_RETRY = "retryInterval";
	
	private static final long KEEP_ALIVE_INTERVAL = 1000*60*28;
	private static final long INITIAL_RETRY_INTERVAL = 1000*10;
	private static final long MAXIMUM_RETRY_INTERVAL = 1000*60*30;
	
	private SocketAdapter socket;
	
	private ConnectivityManager mConnMan;
	private NotificationManager mNotifMan;
	
	public static void actionStart(Context ctx){
		Intent i =new Intent(ctx,PushService.class);
		i.setAction(ACTION_START);
		ctx.startService(i);
	}
	
	public static void actionStop(Context ctx){
		Intent i =new Intent(ctx,PushService.class);
		i.setAction(ACTION_STOP);
		ctx.startService(i);
	}
	
	//send a keep alive message
	public static void actionPing(Context ctx){
		Intent i =new Intent(ctx,PushService.class);
		i.setAction(ACTION_KEEPALIVE);
		ctx.startService(i);
	}
	
	@Override
	public void onCreate() {
		super.onCreate();
		Log.e(TAG, "Creating service");
		mPrefs = getSharedPreferences(TAG, MODE_PRIVATE);
		mConnMan = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
		mNotifMan = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		if(intent.getAction().equals(ACTION_STOP)){
			stop();
		}else if(intent.getAction().equals(ACTION_START)){
			
		}else if(intent.getAction().equals(ACTION_KEEPALIVE)){
			
		}else if(intent.getAction().equals(ACTION_RECONNECT)){
			
		}
		return super.onStartCommand(intent, flags, startId);
	}
	
	/**
	 * 连接服务器
	 */
	private synchronized void connect(){
		String getNowAPN = NetUtil.GetNowAPN(PushService.this);
		if ("cmwap".equals(getNowAPN)) {
			System.getProperties().put("socksProxySet ", "true ");
			System.getProperties().put("socksProxyHost ", GloablParams.PROXY);
			System.getProperties().put("socksProxyPort ", GloablParams.PORT);
		}
		try {
			socket = SocketAdapter.getSocketAdapterInstance(HOST_IP, HOST_PORT);
			startKeepAlives();//心跳
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 开启接收线程
	 */
	private void openReceive(){
		Runnable receiveRunnable =new Runnable() {
			@Override
			public void run() {
				InputStream inputStream = null;
				try{
					Log.i(TAG, "start receive info.");
					socket = SocketAdapter.getSocketAdapterInstance();
					inputStream = socket.openInputStream();
					while(socket.isSendSwitch()){
						//读取数据进行解析
						//final MessageItem  msgItem =NetUtil.readData(inputStream);  //读取数据
						//将数据放入线程池中进行解析
						MessageUtil.receivePoolExecutorService.execute(new Runnable() {
							
							@Override
							public void run() {
								//MessageUtil.handlMessage(msgItem);
							}
						});
					}
					
				}catch(IOException e){
					Log.e(TAG, "接收消息出错，开始重新连接");
					socket.setSendSwitch(false);
				}finally{
					if(inputStream != null){
						try {
							inputStream.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}
		};
		new Thread(receiveRunnable).start();
	}
	
	/**
	 * 发送消息
	 */
	private void writeInfo(){
		new Thread(new Runnable() {
			@Override
			public void run() {
				Log.i(TAG, "start send info");
				try {
					while(socket.isSendSwitch()){
						MessageItem msgItem = MessageUtil.getMsgItem();
						NetUtil.sendData(socket.openOutputStream(), msgItem);
					}
				} catch (IOException e) {
					Log.e(TAG, "发送消息失败开始重新连接!准备开始重新连接");
					socket.setSendSwitch(false);
				}
			}
		}).start();;
	}
	
	private void handleCrashService(){
		if(wasStarted() == true){
			Log.e(TAG, "Handling crashed service....");
		}
	}
	
	private synchronized void stop(){
		if(mStarted == false){
			Log.e(TAG, "Attempt to stop connection not active.");
			return;
		}
		setStarted(false);
		cancelReconnect();
	}
	
	private synchronized void keepAlive(){
		Heart.MessageHeart.Builder builder = Heart.MessageHeart.newBuilder();
		builder.setId(100);
		MessageItem msgItem =new MessageItem();
		msgItem.setMsgType(MessageType.MSG_HEART);
		msgItem.setMsgContent(builder.build().toByteArray());
		MessageUtil.insertSendQueue(msgItem);
	}
	
	private void startKeepAlives(){
		Intent i=new Intent();
		i.setClass(this, PushService.class);
		i.setAction(ACTION_KEEPALIVE);
		PendingIntent pi =PendingIntent.getService(this, 0, i, 0);
		AlarmManager alarmMgr =(AlarmManager) getSystemService(ALARM_SERVICE);
		alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, 
				System.currentTimeMillis()+KEEP_ALIVE_INTERVAL,
				KEEP_ALIVE_INTERVAL, pi);
	}
	
	private void stopKeepAlives(){
		Intent i =new Intent();
		i.setClass(this, PushService.class);
		i.setAction(ACTION_KEEPALIVE);
		PendingIntent pi =PendingIntent.getService(this, 0, i, 0);
		AlarmManager alarmMgr =(AlarmManager) getSystemService(ALARM_SERVICE);
	    alarmMgr.cancel(pi);
	}
	
	public void scheduleReconnect(long startTime){
		long interval = mPrefs.getLong(PREF_RETRY, INITIAL_RETRY_INTERVAL);
		long now = System.currentTimeMillis();
		long elapsed = now - startTime;
		if(elapsed < interval){
			 interval = Math.min(interval * 4, MAXIMUM_RETRY_INTERVAL);
		}else{
			interval = INITIAL_RETRY_INTERVAL;
		}
		mPrefs.edit().putLong(PREF_RETRY, interval).commit();
		Intent i = new Intent();
		i.setClass(this, PushService.class);
		i.setAction(ACTION_RECONNECT);
		PendingIntent pi = PendingIntent.getService(this, 0, i, 0);  
        AlarmManager alarmMgr = (AlarmManager)getSystemService(ALARM_SERVICE);  
        alarmMgr.set(AlarmManager.RTC_WAKEUP, now + interval, pi);
	}
	
	public void cancelReconnect(){
		Intent i =new Intent();
		i.setClass(this, PushService.class);
		i.setAction(ACTION_RECONNECT);
		PendingIntent pi =PendingIntent.getService(this, 0, i, 0);
		AlarmManager alarmMgr =(AlarmManager) getSystemService(ALARM_SERVICE);
	    alarmMgr.cancel(pi);
	}
	
	private boolean wasStarted(){
		return mPrefs.getBoolean(PREF_STARTED,false);
	}
	
	private void setStarted(boolean started){
		mPrefs.edit().putBoolean(PREF_STARTED, started).commit();
		mStarted = started;
	}
	
	
	
	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}

}
